VisualHMI - Lua 脚本API函数接口

本文档适用于VisualHMI平台,Lua脚本语言为V5.3版本,配合工程可以完成大部分的内部逻辑处理, MCU可以只参与数据传输部分,不参与逻辑处理。点击菜单工程栏→脚本编程, 默认在工程目录下生成main.lua,且自动定义变量的数据类型,假设工程当前为modbus协议,如下所示:

ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器


function on_init()
end

function on_run(screen)
end

function on_update(slave,vtype,addr)
end

function on_draw(screen_id,control_id)
end

定义的数据类型:VT_0x线圈、VT_1x离散输入、VT_3x输入寄存器,VT_4x保持寄存器。在读(get_uint16/get_int16...)、写(set_uint16/set_int16)、on_update中vtype的变量类型,对应定义的变量,如下所示:

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器


function on_init()
    set_bit(VT_0x,0x0000,1) --modbus 协议,设置线圈0x0000地址的值为1
    local val = get_bit(VT_1x,0x0000) --modbus 协议,获取离散输入0x0000地址的值
    set_uint16(VT_4x,0x1000, 1) --modbus 协议,设置保持寄存器0x1000地址的值为1
    local val = get_uint16(VT_3x,0x1000) --modbus 协议,获取输入寄存器0x1000的值
end

function on_update(slave,vtype,addr)
    if slave == 0
    then
        if vtype == VT_4x
        then
            .....
        end
    end
end

1 常用回调函数

1.1 on_init()

系统加载LUA脚本文件之后,立即调用此回调函数,通常用于执行初始化操作

ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_init()
    dofile('test.lua')--分多文件编辑,加载其他lua文件
    set_uint16(VT_4x, 0x0000, 1)--初始化寄存
end

1.2 on_run(screen)

系统不断循环调用该函数

set_run_cycle(cycle)可设置执行周期(毫秒单位)

  • screen:当前画面ID

[!note|tip:注意] 错误用法1:系统默认周期,不断设置从机寄存器,导致堵塞

正确用法:on_run周期长,如set_run_cycle(1000),或有条件限制,成立后才设置值

ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_run(screen)

    set_uint16(VT_4x, 0x0000, 1) --不恰当用法

------------------------------------------------------------------------
------------------------------------------------------------------------
    --正确用法
    local start  = get_uint16(VT_4x, 0x1000) --开机状态
    local dstVol = get_uint16(VT_4x, 0x1001) --设置电压
    local curVol = get_uint16(VT_4x, 0x1001) --当前电压
    if dstVol > curVol and start == 1 --设备开启后,当前电压不等于目标电压,设置当前电压值
    then
        set_uint16(VT_4x, 0x1002, 1) --设置频率
    end
end

1.3 on_update(slave, vtype, addr)

变量被设置、更改后,自动执行此函数

  • slave:站号索引,0开始
  • vtype:变量类型,生成main.lua,自动定义变量的数据类型
  • addr:变量地址

[!note|tip:注意] 1.串口指令修改寄存器值,不会触发on_update回调

2.在on_update函数里,调用set_uit16(set_int16/set_uint32...), 不会在触发on_update回调

3.在其他系统回调函数,如on_init ,执行set_uit16(set_int16/set_uint32...) ,会触发on_update回调

4.用户点击屏幕,修改控件状态(寄存器值),会触发on_update回调

如下所示,以Modbus 协议为例,当其他回调函数设置寄存器,均不想触发on_update回调,可以定义全局变量如下处理:

ENCRYPT_=0    --LUA脚本加密

EN_ON_UPDATE_API_CB = 1 --全局变量,其他回调函数设置寄存器时,为1执行,为0直接退出

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_init()
    EN_ON_UPDATE_API_CB = 0

    --user code
    set_uint16(VT_LW, 0x10000x55AA)

    EN_ON_UPDATE_API_CB = 1
end

function on_run(screen)
    EN_ON_UPDATE_API_CB = 0
    --user code
    EN_ON_UPDATE_API_CB = 1
end

function on_update(slave, vtype, addr)
    if EN_ON_UPDATE_API_CB == 0
    then
        return
    end

    if slave == 0
    then
        if vtype == VT_4x --保持寄存器
        then
            if addr == 0x1000
            then
                local val = get_uint16(VT_4x, addr)   
                if val == 1
                then
                    set_uint16(VT_4x, 0x0001, val) 
                end
            end
        elseif vtype == VT_0x --线圈
        then
            if addr == 0x0000
            then
                local val = get_uint16(VT_0x, addr)
                if val == 1
                then
                    set_uint16(VT_0x, 0x0001, val) 
                end
            end
        end
    end

    if vtype == VT_LW --内部寄存器
    then
        if addr == 0x1000
        then
            local val = get_uint16(VT_LW, addr)
            if 0x55AA == val
            then
                 set_uint16(VT_4x, 0x0000, val)  
            end
        end
    end
end

function on_draw(screen_id,control_id)
    EN_ON_UPDATE_API_CB = 0

    --user code

    EN_ON_UPDATE_API_CB = 1
end

function on_screen_change(screen)
    EN_ON_UPDATE_API_CB = 0

    --user code
    if screen == 1
    then
        set_bit(VT_0x, 0x0000, 1)
    end

    EN_ON_UPDATE_API_CB = 1
end

1.4 on_screen_change(screen)

当画面切换时,自动执行此函数

  • screen:目标画面ID

1.5 on_press(state, x, y)

点击屏幕触发坐标通知,100ms回调一次

  • state:1-按下,2-长按,0-弹起
  • x:x轴坐标
  • y:y轴坐标通知

1.6 on_usb_inserted(driver)

U盘插入时,执行此回调函数,dirver为U盘的盘符

1.7 on_usb_removed()

U盘拔出时,执行此回调函数

1.8 on_sd_inserted(dir)

SD卡插入通知,dir盘符路径

1.9 on_sd_removed()

SD卡拔出通知

2 读写寄存器函数

2.1 set_notify(enable)

使能串口通知,启用后设置变量的值可触发串口命令发送。

  • enable:0禁止,1使能(默认值)
--如DCBUS协议下,设置0x1000地址,不通过串口下发给主板:
set_notify(0) -- 禁止通知
set_uint16(VT_LW, 0x1000, 1)--设置参数
set_notity(1)-- 启用通知

2.2 select_slave(slave_id)

选择从站地址,用于多从机模式,如MODBUS、FX2N协议

  • slave_id:从机索引

image-20231107094626802

如modbus 协议中,总线有2个从机,第一个从机站号10,第2个从机站号为33,可封装如下函数:

--读取保持寄存器
function mb_read_reg_03(slave, addr)
    local onlineState = get_uint16(VT_LW, 0x01A3) --从机在线掩码,bitx = 1在线
    if (onlineState >> slave) & 0x01 == 0x01
    then
        select_slave(slave) --选择从机
        return get_uint16(VT_4x, addr)--获取寄存器值
    else
        return false
    end
end

--设置保持寄存器
function mb_write_reg_06(slave, addr, value)
    local onlineState = get_uint16(VT_LW, 0x01A3) --从机在线掩码,bitx = 1在线
    if (onlineState >> slave) & 0x01 == 0x01
    then
        feed_dog()--喂狗
        select_slave(slave)--选择从机
        set_uint16(VT_4x, addr, value)--设置寄存器值
    end
end

local val1  = mb_read_reg_03(0, 0x1000)--读取从机1,站号10,寄存器地址0x1000
local val2  = mb_read_reg_03(1, 0x1000)--读取从机2,站号33,寄存器地址0x1000

mb_write_reg_06(0, 0x2000,val1)--设置从机1,站号10,寄存器地址0x1000值为val1
mb_write_reg_06(1, 0x2000,val2)--设置从机1,站号33,寄存器地址0x1000值为val2

2.3 set_endian(en)

设置变量的大小端,在主从机模式下生效

  • en:0-大端(默认值),1-小端

2.4 set_bit(vtype, addr, value)

设置位寄存器:如Modbus的线圈、Fx2N的X、Y、S、M寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_bit(VT_0x, 0x0000, 1) --设置线圈0x0000地址的状态1

2.5 get_bit (vtype, addr)

读取位寄存器:如Modbus的线圈、Fx2N的X、Y、S、M寄存器,返回数值

  • vtype:数据类型
  • addr:变量地址
local state = get_bit(VT_0x, 0x0000) --获取线圈0x0000地址的状态

2.6 set_uint16(vtype, addr, value)

设置无符号短型(uint16)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_uint16(VT_LW, 0x1000, 12345) --设置屏幕内部寄存器0x1000地址为12345

2.7 get_uint16(vtype, addr)

读取无符号短型(uint16)寄存器

  • vtype:数据类型
  • addr:变量地址
local val = get_uint16 (VT_LW, 0x1000) --获取屏幕内部寄存器0x1000地址的值

2.8 set_int16(vtype, addr, value)

设置有符号短型(int16)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_int16(VT_LW, 0x1000, 12345) --设置屏幕内部寄存器0x1000地址为-12345

2.9 get_int16(vtype, addr)

读取有符号短型(int16)寄存器

  • vtype:数据类型
  • addr:变量地址
local val = get_int16 (VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.10 set_uint32(vtype, addr, value)

设置无符号短型(uint32)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_uint32(VT_LW, 0x1000, 123456) --设置屏幕内部寄存器0x1000地址为123456

2.11 get_uint32(vtype, addr)

获取无符号短型(uint32)寄存器

  • vtype:数据类型
  • addr:变量地址
local val = get_uint32 (VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.12 set_int32(vtype, addr, value)

设置有符号短型(int32)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_uint32(VT_LW, 0x1000, -123456) --设置屏幕内部寄存器0x1000地址为-123456

2.13 get_int32 (vtype, addr)

读取有符号整型(int32)寄存器

  • vtype:数据类型
  • addr:变量地址
local val = get_int32(VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.14 set_uint64(vtype, addr, value)

设置无符号长整型(uint64)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_uint64(VT_LW, 0x1000, 1234567890) --设置屏幕内部寄存器0x1000地址为1234567890

2.15 get_uint64 (vtype, addr)

读取无符号整型(int64)寄存器

  • vtype:数据类型
  • addr:变量地址
local val = get_uint64(VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.16 set_int64 (vtype, addr, value)

设置有符号长整型(int64)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_int64(VT_LW, 0x0000, -1234567890)--设置屏幕内部寄存器0x1000地址为-1234567890

2.17 get_int64 (vtype, addr)

读取有符号整型(int64)寄存器

  • vtype:数据类型
  • addr:变量地址
local value = get_int64(VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.18 set_float(vtype, addr, value)

设置单精度浮点数(float)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_float(VT_LW, 0x10001.234)--设置屏幕内部寄存器0x1000地址为1.234

2.19 get_float (vtype, addr)

读取单精度浮点数(float)寄存器

  • vtype:数据类型
  • addr:变量地址
local val = get_float(VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.20 set_double(vtype, addr, value)

设置双精度浮点数(doubule)寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_double(VT_LW, 0x1000,1.23456789)--设置屏幕内部寄存器0x1000地址为1.23456789

2.21 get_double (vtype, addr)

设置双精度浮点数(doubule)寄存器

  • vtype:数据类型
  • addr:变量地址
local value = get_double(VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.22 set_string(vtype, addr, strings)

设置字符串类型寄存器

  • vtype:数据类型
  • addr:变量地址
  • value:写入的值
set_string(VT_LW, 0x1000'https://www.gz-dc.com/')--设置屏幕内部寄存器0x1000地址为https://www.gz-dc.com/

2.23 get_string(vtype, addr)

读取字符串变量

  • vtype:数据类型
  • addr:变量地址
local string = get_string (VT_LW, 0x1000)--获取屏幕内部寄存器0x1000地址的值

2.24 set_uint16_ex(vtype, addr, value1,value2, …, value120)

  • vtype:数据类型
  • addr:变量起始地址,最大可以写120个连续寄存器
  • value1:寄存器1的值
  • value2:寄存器2的值
  • ……
  • value120: 寄存器120的值
local r_addr = 0x6060
set_uint16_ex(vtype, r_addr,
        1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
        21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
        41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
        61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
        81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,  101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120)

2.25 set_array(vtype, addr, buff)

  • vtype:数据类型
  • addr:变量起始地址,最大可以写120个连续寄存器
  • buff:word(字)数组,最大120个字
local buff = {}
local r_addr = 0x6060
local index = 120
local data  = 0
for i = 1, 120
do
    buff[i] = i
end
set_array(vtype, r_addr, buff)

2.26 start_read(index,vtype, addr,quantity)

开始读取多个连续的变量,系统自动发指令读取变量地址

[!note|tip:注意] 1.只能用于主机模式,例如Modbus-Master、FX2N等

2.调用一次,屏幕会周期性发指令请求,停止需要调用stop_read

3.该函数没有返回值,需要配合get_xx获取寄存器的值

4.当前画面用到的变量地址或者有配置告警、资料采集,系统会自动读取,无需使用start_read。

5.若当前画面的控件绑定变量地址或者有配置告警、资料采集,脚本调用的start_read和前者有交叉部分,系统会优化读取指令,重新整合指令请求

  • index:索引,通常和停止读取搭配stop_read
  • vtype:数据类型
  • addr:开始读取的地址
  • quantity:读取的个数,最大120
ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_init()
    start_read(0, VT_4x, 0x0000, 10)--任意界面均会发送指令请求4x0000~4x000A寄存器指令
end

2.27 stop_read(index)

停止读取多个连续的变量

[!note|tip:注意] 只能用于主机模式,例如Modbus-Master、FX2N等

  • index:索引,通常和开始读取搭配start_read

2.28 stop_all_read()

停止所有start_read开启的读取指令

[!note|tip:注意] 只能用于主机模式,例如Modbus-Master、FX2N等

2.29 set_auto_read(en)

使能画面控件绑定的寄存器自动读取

[!note|tip:注意] 1.只能用于主机模式,例如Modbus-Master、FX2N等

2.set_auto_read(0),禁止后,用start_read 控制读取

3.画面的控件绑定寄存器,默认自动读取

  • en:0-画面禁止自动读取,1-画面自动读取

3 绘图函数

3.1 on_draw(screen,control)

控件自绘接口函数,要使用自绘功能,控件ID不能为0。

当界面的显示内容需要更新时,系统自动调用此函数,用户在此函数中添加自定义的绘图操作。

[!note|tip:注意] 1.该函数为系统回调函数,用户不要直接调用

2.相关draw_xx 图形,需要在该回调函数里面调用执行

下面几种情况会触发此函数:

  • 界面有动画播放、视频播放、RTC时间显示的动态刷新;
  • 用户操作屏幕控件控件;
  • 通过LUA脚本或串口指令更新控件;
  • 通过执行redraw

若要绘制的图形有上下图层关系,如图片1绘制到图片2上层,可通过建立不同“画板”id实现。如下所示,添加两个矩形框作为“画板”,其中层次关系,从下到上依次为文本控件→蓝色矩形→黄色矩形

image-20231107105022458

结合Lua脚本,在on_draw(...)判读对应的画面、对于控件id,即可绘制到“控件”上层或“已绘制的图形”上。如绘制“水果图片”到蓝色画板上,绘制“小岛图片”到黄色背景上,如下所示

image-20231107105443307

function on_draw(screen_id, control_id)
    if screen_id == 0 and control_id == 1
    then
        draw_surface(surface[1], 293, 88, 222, 353, 0, 0)  --裁剪显示

    elseif screen_id == 0 and control_id == 2
    then
        draw_surface(surface[2], 314, 158, 180, 250, 0, 0) --裁剪显示
    end
end

“画布”的大小、位置、类型可以任意,若控件ID、层叠顺序确定好后,一般情况建议如下所示:

[!note|tip:注意] 1.控件类型:静态的控件,如文字、直线、矩形、圆形等,防止被误触或者设置

2.画布大小:1*1大小

3.画布位置:放在不显眼的角落、或编辑区外

image-20231107105624129

3.2 redraw()

发起重绘请求,触发on_draw的执行。

3.3 set_pen_color(color)

设置画笔的颜色,RGB565,用于指定线、矩形、圆等的颜色

  • color:RGB565颜色值

3.4 draw_line(x0,y0,x1,y1,width)

绘制直线

  • x0,y0:起始点坐标
  • x1,y1:结束点坐标
  • width:为线条的厚度,1~10
draw_type = 0

mode = {  --绘制类型表
    line = 1,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr) --获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.line] = function(control)
            if screen_id == 0 and control == 1
            then
                --设置画笔黄色划线
                set_pen_color(0xFFE0)
                draw_line(225, 253, 405, 253)

                --设置画笔红色,划线
                set_pen_color(0xF800)
                draw_line(508, 128, 508, 378, 5) 
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.5 draw_rect(x0,y0,x1,y1,fill)

绘制矩形

  • x0,y0:左上角坐标
  • x1,y1:右下角坐标
  • fill:0不填充,1填充
draw_type = 0

mode = {  --绘制类型表
    rect = 2,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr)--获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.rect] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制矩形
                draw_rect(225, 128, (225+180), (128+250), 0)
                draw_rect(418, 163, (418+180), (128+180), 1) 
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end
end

3.6 draw_rect_alpha(x0,y0,x1,y1,alpha)

绘制实心的半透明矩形,F系列不支持

  • x0,y0:左上角坐标
  • x1,y1:右下角坐标
  • alpha:透明度0全透明~255不透明
draw_type = 0

mode = {  --绘制类型表
    rect_alpha = 3,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr)--获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.rect_alpha] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制半透矩形
                draw_rect_alpha(225, 128, (225+180), (128+250), 30)
                draw_rect_alpha(418, 163, (418+180), (128+180), 60)
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.7 draw_circle(x,y,r,fill)

绘制圆形

  • x,y:圆的中心坐标
  • r:圆的半径
  • fill:0不填充,1填充
draw_type = 0

mode = {  --绘制类型表
    circle = 4,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr)--获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.circle] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制圆形
                draw_circle(300, 253, 100, 0)
                draw_circle(450, 253, 150, 1)
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.8 draw_ellipse(x0,y0,x1,y1,fill)

绘制椭圆

  • x0,y0:左上角坐标
  • x1,y1:右下角坐标
  • fill:0不填充,1填充
draw_type = 0

mode = {  --绘制类型表
    ellipse = 5,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr)--获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.ellipse] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制椭圆
                draw_circle(300, 253, 100, 0)
                draw_circle(450, 253, 150, 1)
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.9 draw_image(image_id,frame_id,dstx,dsty,width,height,srcx,srcy)

绘制图片

  • image_id图片资源的ID
  • frame_id对应图标,可以设置帧ID,其他图片固定为0
  • dstx图片显示X坐标
  • dsty图片显示Y坐标
  • width图片显示宽度
  • height图片显示高度
  • srcx图片裁剪X坐标
  • srcy图片裁剪Y坐标

[!note|tip:如何确定image_id] 1.在工程目录下的../build/文件夹,打开image.xml文件,image id = "xx"表示第一个参数

image-20231107110143684

draw_type = 0

mode = {  --绘制类型表
    imageId = 6,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr)--获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.imageId] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制图片
                draw_image(1, 0, 225, 128, (225+180), (128+250), 0, 0)
                draw_image(2, 0, 418, 163, (418+180), (128+180), 0, 0)
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.10 draw_text(text,x,y,w,h,font_id,size,color,align)

显示文字,text字符串

  • x显示X坐标
  • y显示Y坐标
  • w显示宽度
  • h显示高度
  • font_id:索引
  • size:字体大小
  • color颜色RGB565
  • align对齐方式
  • bit0~bit1水平对齐方式,0左对齐,1居中对齐,2右对
  • bit2~bit3垂直对齐方式,0上对齐,1居中对齐,3下对齐
draw_type = 0

mode = {  --绘制类型表
    text          = 7,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        draw_type = get_uint16(VT_LW, addr)--获取字设置按钮键值
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.text] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制文字
                draw_text('广州大彩光电科技有限公司\nCopyright? gz-dc.com ', 195, 96, 408 ,318, 0, 32, 0xF800, 5, 1) 
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.11 load_surface (filename)

加载图片到图层

  • filename:图片文件,支持JPEG/PNG
if surface > 0
then
    destroy_surface(surface)
end
surface = load_surface('3:/test.jpg')

[!note|tip:注意] 1.工程有播放视频功能,不支持绘制jpg图片

2.一般用于替换logo,客户从U盘/SD卡拷贝到屏内,替换logo

3.png 比较占运行内存信息

3.12 destroy_surface (surface)

销毁图层

  • surface:图层资源指针
destroy_surface(surface)

3.13 destroy_all_surface()

销毁所有图层指针

3.14 draw_surface (surface,dstx,dsty,width,height,srcx,srcy)

绘制图层,支持绘制jpg、png格式的图片,在on_draw()系统函数里调用

  • surface:图层资源指针
  • dstx:图片显示X坐标
  • dsty:图片显示Y坐标
  • width:图片显示宽度[可选]
  • height:图片显示高度[可选]
  • srcx:图片裁剪X坐标[可选]
  • srcy:图片裁剪Y坐标[可选]

例如:

draw_type = 0
surface = 0
mode = {  --绘制类型表
    surface_path3 = 8,
}

function on_update(slave,vtype,addr)

    if addr == 0x1000
    then
        if surface > 0
        then
            destroy_surface(surface)
        end
        surface = load_surface('3:/test.jpg')
        --surface = load_surface('1:/test.jpg') --SD卡图片
        --surface = load_surface('2:/test.jpg') --U盘图片
        redraw()--绘图
     end
end

function on_draw(screen_id,control_id)

   local switch = {
        [mode.surface_path3] = function(control)
            if screen_id == 0 and control == 1
            then
                --绘制图片
                draw_surface(surface, 175, 60, 222, 353, 0, 0)
            end
        end,
    end

    if switch[draw_type]
    then
        switch[draw_type](control)
    end 
end

3.15 get_surface_size (surface)

获取指定图层指针的图像大小,返回,宽度和高度

  • surface:图层资源指针
local cur_w,cur_h = get_surface_size (surface)

3.16 clear_image_buffer()

清除内部图片资源缓存

3.17 screen_shoot(filepath)

截取整个屏幕的内容,保存为jpg图片。

  • filepath:图片存储路径

4 数据记录

4.1 record_get_count(sn)

获取该笔资料的记录数

  • sn:资料记录索引,从0开始
local cnt = record_get_count(idx)

4.2 record_modify_data(sn, index, data)

修改数据记录的内容

[!note|tip:注意] 若开启存储模式,则不允许修改记录

  • sn:资料记录索引,从0开始
  • index:记录的行号,从0开始
  • data:字数组(word),下表从1开始

假设修改第0笔资料,为uint16,共100个数据,则修改第0行记录为1~100实例如下:

for i = 1, 100
do
    dataTb[i] = i
end
record_modify_data(0, 0, data)

假设修改第0笔资料,为uint32,共100个数据,则修改第0行记录为1~100实例如下:

for i = 1, 200
do
    if i % 2 == 0
    then
        dataTb[i] = i
    else
        dataTb[i] = 0
    end
end
record_modify_data(0, 0, data)

uint32共100个参数,共占200个字,所有,data的大小为200。依次类推,64位寄存器为400

4.3 record_write_data(sn, data)

添加数据记录的内容

  • sn:资料记录索引,从0开始
  • data:字数组(word),下表从1开始

假设第0笔资料为uint16,共100个数据,添加一条记录,则添加内容为1~100实例如下:

for i = 1, 100
do
    dataTb[i] = i
end
record_write_data(0, data)

假设第0笔资料为uint32,共100个数据,添加一条记录,则添加内容为1~100实例如下:

for i = 1, 200
do
    if i % 2 == 0
    then
        dataTb[i] = i
    else
        dataTb[i] = 0
    end
end
record_write_data(0, data)

4.4 record_read_data(sn, index)

读取数据记录的内容

  • sn:资料记录索引,从0开始
  • index:记录的行号,从0开始

返回两个参数:data, timestamp

  • data:字数组,数据内容,下标从1开始
  • timestamp:时间戳,32位

假设第0笔资料为uint16,共100个数据,读取第0笔资料,第1行数据

local data,timestamp =  record_read_data(0, 0) 
print'size'..(#data))

>size = 100

假设第0笔资料为uint32,共100个数据,读取第0笔资料,第1行数据

local data,timestamp =  record_read_data(0, 0) 
print'size'..(#data))

>size = 200

4.5 record_modify_string(sn, index, strings)

修改字符串类型的数据记录

[!note|tip:注意]

若开启存储模式,则不允许修改记录

  • sn:资料记录索引,从0开始
  • index:记录的行号,从0开始
  • strings:字符串。每一列用“;”隔开;
--修改第0笔资料,第1行数据的数据为‘item1;item2;item3;item4;item5;’
record_modify_string(0, 0,‘item1;item2;item3;item4;item5;’)

4.6 record_read_string(sn, index)

读取字符串类型的数据记录

  • sn:资料记录索引,从0开始
  • index:记录的行号,从0开始

返回两个参数:strings, timestamp

  • strings:字符串。每一列以“;”隔开
  • timestamp:时间戳
local strings, timestamp = record_read_string(0, 0)
print(‘strings = ’..strings)

> strings = item1;item2;item3;item4;item5;

4.7 record_write_string(sn, strings)

添加数据记录的内容

  • sn:资料记录索引,从0开始
  • strings:字符串,每一列参数以“;”隔开
--第0笔资料,添加一条记录‘item1;item2;item3;item4;item5;’
 record_write_string( 0,‘item1;item2;item3;item4;item5;’)

4.8 record_clear(sn)

清除记录

  • sn:资料记录索引,从0开始

5 告警

一般情况使用告警设置对话框就可以满足告警需求,不需要使用下面的API。

此处的告警指通过脚本触发告警和动态显示告警内容

用于如下情形:

  • 告警条目比较多,内容具有重复规律,只有细微差异
  • 告警条件具有规律性

5.1 warning_set_mode(en)

开启告警模式之后,warning_set才能生效

  • en:0关闭,1开启告警触发模式
ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储

function on_init()
    warning_set_mode(1) --LUA解析告警
end

5.2 warning_set(warning_id,value,count)

触发或关闭指定id位置的告警,此功能需要提前设置warning_set_mode(1)

  • warning_id:起始告警id
  • value: 告警值,对应的bit为1触发告警,为0关闭告警。
  • count:连续告警个数
--读取寄存器值
local err_val = get_uint16(VT_V, 0x1D00)

--将寄存器值的每一个位,对应到告警0~15范围
warning_set(0, err_val , 16)

5.3 on_parse_warning(id, text)

告警解析回调函数,通过判断告警id,返回描述告警内容的字符串。

参数说明:

  • warning_id:告警ID
  • value: 告警内容

返回参数说明:

  • str:返回的字符串告警内容

  • encode:字符号编码。选填,默认为UTF8。若encode=1,则表示UTF8编码

_warningTb = {
--1~96
    '翅片1温度探头故障',
    '翅片2温度探头故障',
    '翅片3温度探头故障',
    '翅片4温度探头故障',
    '回气1温度探头故障',
    '回气2温度探头故障',
    '回气3温度探头故障',
    '回气4温度探头故障',
    '排气1温度探头故障',
    '排气2温度探头故障',
    '排气3温度探头故障',
    '排气4温度探头故障',
    '蒸发1温度探头故障',
    '蒸发2温度探头故障',
    '蒸发3温度探头故障',
    '蒸发4温度探头故障',

    '冷凝1温度探头故障',
    '冷凝2温度探头故障',
    '冷凝3温度探头故障',
    '冷凝4温度探头故障',
    '房内温度探头故障',
    ...
    ...
    ...
    '室内翅片1探头故障',
    '室内翅片2探头故障',
    '室内翅片3探头故障',
    '室内翅片4探头故障',
}

function on_parse_warning(id, text)

--设备1:id0~id95
--...
--...
--...
--设备8:id673~id768

    local slaveId = (id // 96) + 1   --第几个告警
    local msgId = id % 96            --告警类型ID
    local curWarnMsg = ''            --告警描述

    msgId = (msgId == 0) and 1 or (msgId + 1)
    curWarnMsg = math.ceil(slaveId)..'device : '.._warningTb[msgId]

    return curWarnMsg
end

6 定时器

6.1 start_timer(timer_id, timeout, countdown, repeat)

启动定时器,超时后系统自动调用on_timer

  • timer_id-定时器ID,0~31
  • timeout-超时时间,单位毫秒
  • countdown-0顺计时,1倒计时
  • repeat-重复次数,0表示无限重复

6.2 stop_timer(timer_id)

停止定时器

  • timer_id-定时器ID,0~31

6.3 on_timer(timer_id)

定时器超时回调函数

  • timer_id-定时器ID,0~31

如初始化开启1s超时,无限循环的定时器,则每秒输出“hello lua”

function on_timer(timer_id)
    if timer_id == 0
    then
        print('hello lua!!!')
    end
end

function on_init()
    start_timer(0, 1000, 0, 0)    
end

>hello lua!!!
>hello lua!!!
>...

6.4 get_timer_value(timer_id)

获取定时器当前计时时间,单位毫秒

  • timer_id-定时器ID,0~31

7 串口

7.1 uart_setup(ch,baudrate,databits,stopbit,parity)

串口参数设置

  • ch:串口通道,0-主串口
  • baudrate:波特率值
  • databits:数据位,7表示7位,8表示8位
  • stopbit:停止位,0-1bit,1-1.5bit
  • parity:0-无校验,1-ODD奇校验,2-EVEN 偶校验

[!note|tip:注意]

DCBUS、XGUS协议不支持设置停止位、校验位。固定1个停止位、无校验

7.2 on_uart_recv(ch,packet)

串口接收回调,自定义串口协议模式时才会触发

  • ch:串口通道,默认0
  • packet:字节数组,下标从1开始

[!note|tip:自由串口协议]

需要用户处理粘包、分包处理,该串口回调非中断触发

以下面指令格式为例:

HEAD COMMAND LENG DATA1 DATA2 …. CHECKSUM TIE
0x02 功能码 数据长度 数据1 数据2 校验值 0x03

说明:

  • HEAD:包头-固定值0x02
  • COMMAD:功能码
  • LEND:DATA的长度
  • DATA:N个字节
  • CHECKSUM:HEAD+COMMAND+LENG+DATA字段,求和后取低8位
  • TIE:包尾-固定值0x03
_Com_HEAD_ = 0x02 --BT协议数据包头
_Com_TAIL_ = 0x03 --BT协议数据包尾

--串口接收缓存表示
Com.cmd = {
    head_tag = 0, --检测头标识
    head     = 0, --存放头字节
    tail     = 0, --存放尾字节
    buff     = {}, --指令缓存
    len      = 0, --指令长度
    datalen  = 0  --内容长度
}

-- 校验和
function CheckSum(data)

    local result = 0

    for i = 1, (#data - 2)
    do
        result = result + data[i]
    end
    result = result & 0xFF


    return result
end

--BT协议数据包解析
function __ProtocolParse(data)

    --用户代码区域,完整一帧指令提取出来,实现用户业务逻辑
end

function Com.dataRecv(packet)
    --拼凑数据包
    for i = 1, #(packet) 
    do
        Com.cmd.head = packet[i] & 0xFF
        if Com.cmd.head == _Com_HEAD_ and Com.cmd.head_tag == 0 --检测到BT帧头
        then
            Com.cmd.head_tag = 1
        end

        if Com.cmd.head_tag == 1 --已经检测到帧头
        then

            Com.cmd.len = Com.cmd.len + 1 --计算指令长度
            Com.cmd.buff[Com.cmd.len] = packet[i] -- 填充buff

            Com.cmd.tail = packet[i] & 0xFF
            if Com.cmd.tail == _Com_TAIL_ ----检测到BT帧尾部
            then
                Com.cmd.datalen = Com.cmd.buff[3]     -- LEND : HEAD + ComAND + DATA的长度
                if Com.cmd.datalen == Com.cmd.len - 5 -- LEND = CMD_SIZE - (LENG + CRC_VALUE + TIE)
                then
                    if CheckSum(Com.cmd.buff) == Com.cmd.buff[#Com.cmd.buff - 1]
                    then
                        --提取完整的一帧指令
                        __ProtocolParse(Com.cmd.buff)
                    end

                    Com.cmd = { --初始化,情况串口相关标识、缓存区
                        head_tag = 0,
                        tail     = 0,
                        buff     = {},
                        len      = 0,
                        datalen  = 0
                    }
                end
            end
        end
    end
end

function on_uart_recv(ch,packet)
    Com.dataRecv(packet)
end

7.3 uart_send(ch,packet)

发送字节数组

  • ch:串口通道,默认0
  • packet:数组,下标从1开始

指令格式说明参考1.8.2章

_Com_HEAD_ = 0x02 --BT协议数据包头
_Com_TAIL_ = 0x03 --BT协议数据包尾
-- 校验和
function CheckSum(data)

    local result = 0

    for i = 1, (#data - 2)
    do
        result = result + data[i]
    end
    result = result & 0xFF


    return result
end

function Com.dataSend(func, data)

    local buff = {}

    local dataLen = 0
    if data ~= nil
    then
        dataLen = #(data)
    else
        dataLen = 0
    end

    buff[1] = _Com_HEAD_
    buff[2] = func
    buff[3] = dataLen

    if dataLen > 0
    then
        for i = 1, #data
        do
            buff[3 + i] = data[i]
        end
    end

    buff[#buff + 1] = 0xFF
    buff[#buff + 1] = _Com_TAIL_

    buff[#buff - 1] = CheckSum(buff)

    uart_send(0, buff)

end

8 音视频

8.1 play_sound(filename)

播放指定的声音文件,例如播放屏内音频文件

  • filename:路径
--屏内路径播放:
M:play_sound("3:/sound/welcome.wav")

--SD路径播放:
M:play_sound("1:/welcome.wav")

--U盘路径播放:
M:play_sound("2:/welcome.wav")

8.2 stop_sound()

停止播放

8.3 play_video(file,left,top,width,height)

播放视频,满足如下格式

播放视频

MP4文件

H264编码

音频流为MP3或AAC格式

视频最大分辨率<1280*768

最大帧数<30ps

最大码率<1400

  • pathname为视频路径

  • left:起始坐标x

  • top:起始坐标y
  • width:视频显示的宽度
  • height:视频显示的高度
--屏内路径播放:
M:play_sound("3:/video/welcome.mp4")

--SD路径播放:
M:play_sound("1:/welcome.mp4")

--U盘路径播放:
M:play_sound("2:/welcome.mp4")

8.4 pause_video()

暂停视频播放

8.5 resume_video()

恢复视频播放

8.6 stop_video()

停止视频播放

8.7 on_video_notify(msg,v1, v2)

视频播放回调函数

msg:1-播放中,0-播放完毕

v1:当前播放进度,当前已播时长,单位s

v2:播放总进度, 当前视频总时长,单位s

8.8 av_init(show,channel,left,top,width,height)

av 输入初始化

  • show:0隐藏,1显示
  • channel:通道编号0/1
  • left:起始坐标x
  • top:起始坐标y
  • width:视频显示的宽度
  • height:视频显示的高度

8.9 av_get_status()

获取AV播放状态

status = av_get_status()

8.10 av_select(ch)

切换AV通道

  • ch:0-切换到通道1,1-切换到通道2
av_select(0) --切换到通道1
av_select(1) --切换到通道2

8.11 av_show(show)

显示/隐藏AV播放

  • show:0-隐藏,1-显示

8.12 video_shoot(filepath, width, height)

截取视频/AV窗口的内容,保存为bmp图片。

注意,默认支持AV截图,视频截图需要特定固件

  • filepath:图片存储路径
  • width:宽度
  • height:高度

8.13 set_color_key(Min_Color,Max_Color,Match)

针对M型系列的视频播放/AV输入功能时,视频图层会一直显示在最上层,此时如果我们将文字等其他图形叠加放在视频控件上显示时,视频图层会将其他图形都覆盖,导致只能显示出视频,而无法显示视频上叠放的其他文字和图形。为此,我司针对有此类需求的客户开发了对应的M系列视频底层播放API接口,来满足此类客户的需求,api函数接口如下所示

参数说明:

  • Min_Color:24位RGB颜色范围的最小值,例如0x00BFBFBF,R-BF/G-BF/B-BF;
  • Min_Color:24位RGB颜色范围的最大值,例如0x00C8C8C8,R-C8/G-C8/B-C8;
  • Match:6位的比较规则101010(2A);10-R/10-G/10-B,代表颜色范围在0x00BFBFBF—0x00C8C8C8之间的颜色值经过比较后会被过滤。(0x00BFBFBF <= color <= 0x00C8C8C8之间的颜色会被过滤,其他颜色会显示出来)
function on_init()
    set_color_key(0x00BFBFBF,0x00C8C8C8,0x0000002A)
endCopy

注:set_color_key(Min_Color,Max_Color,Match),此API接口函数必须要放在on_init()系统初始化函数中使用,默认在初始时配置的属性

9 文件系统操作

9.1 dofile(name)

加载lua文件,用于lua脚本分模块编辑,创建的*.lua文件放在工程目录下,在on_init()里调用即可

function on_init()
    dofile(‘test.lua’)
end

9.2 list_dir(path)

 list_dir('1:')  --遍历SD卡文件
 list_dir('2:')  --遍历U盘文件
 list_dir('3:')  --遍历屏内文件

遍历指定目录下的文件和文件夹

  • path:文件路径
  • filename:文件名称
  • type:0-文件夹,1-文件
  • fsize:文件大小

通过以下回调函数返回文件的内容

on_list_dir(path,filename,type,fsize)

9.3 on_list_dir(path,filename,type,fsize)

  • path-文件路径
  • filename-文件名称
  • type-0 文件夹, 1 文件
  • fsize-文件大小
function on_list_dir(path, filename, type, fsize)

    local msg = ''
    if type == 0 --文件夹
    then
    else --文件
         msg = path..'/'..file_name --文件路径
    end
end

9.4 file_open(path,mode)

打开文件,成功返回true,失败false

  • path-文件路径
  • mode-打开模式,如下组合方式
FA_READ FA_WRITE FA_WRITE_ADD
0x00 0x01 0x02
--打开文件读(没有文件创建文件):
file_open(path, 0x00)

--打开文件覆盖写(没有文件创建文件):
file_open(path, 0x01)

--打开文件末尾写(没有文件创建文件):
file_open(path, 0x02)

9.5 file_close()

关闭文件,成功返回true,失败false

9.6 file_size()

获取当前文件大小,返回字节数

local file_fd = file_open(path, 0x00)
local filesize = file_size()

9.7 file_seek(offset)

定位文件读取位置,成功返回true,失败false

  • offset:文件偏移位置

9.8 file_read(count)

读取文件内容,成功返回table数组,字节数组,下标从1开始,失败返回nil

  • count:读取字节数,最大读取2048个字节
local tb = file_read(2048)

[!note|tip:注意]

每次读取2048个字节,实际使用中,不能将整个文件读出来放在buff缓存在处理,每读一次,处理数据。否者,读取的文件内容大,屏幕内存不够,会重启

9.9 file_write(data)

写文件内容,成功返回true,失败返回false

  • data-待写入的table数组,索引从1开始,最大一次性写2048个字节
local ret = file_write(write_byte_Tb) -- 1 ≤ data 数组大小 ≤ 2048
return ret

9.10 file_delete(path)

  • path:待删除的文件路径
file_delete('1:/1.txt')

9.11 file_copy(src_path, dst_path)

  • src_path:源文件路径
  • dst_path:目标文件路径
file_copy('1:/1.txt', '1:/1_copy.txt') --从SD卡目录下,复制1.txt为1.copy.txt

9.12 on_copy_file_process(status,filesize,transfersize)

文件拷贝进度,配合 file_copy(src_path, dst_path)使用,当调用 file_copy,自动回调到on_copy_file_process函数

  • status:状态.0-失败,1-拷贝中,2-拷贝完成
  • filesize:被拷贝的文件大小
  • transfersize:当前回调拷贝的字节数
function on_copy_file_process(status,filesize,transfersize)

    local progress        = 0

    if status == 0 -- 复制失败
    then

    elseif status == 1 --复制中
    then
        local prg = ((transfersize*100) // filesize) --计算百分比进度

    elseif status == 2 -- 复制成功
    then   
    end

    refresh_screen()-- 刷新界面
end

10 设置窗口

API函数中的screen、control参数均表示为目标画面ID、目标组态控件ID。控件ID需要用户编号,默认为0,需要设置非0才生效

image-20231107152217615

10.1 set_screen(screen)

设置当前画面,执行画面切换

  • screen:目标画面ID

10.2 get_screen()

获取当前画面ID

--EG:
local page = get_screen()

10.3 show_dialog(screen, x, y, alpha)

设置对话框,执行切换对话框操作

  • screen:画面ID
  • x,y:左上角起始位置
  • alph:透明度
show_dialog(0, 184, 108, 50) --显示对话框,坐标(184,105),50%的透明度
show_dialog(-1, 184, 108, 50) ---1,表示关闭对话框,后面参数任意

10.4 wgt_set_pos(screen,control,x,y,w,h)

设置控件的位置

  • screen:画面ID
  • control:控件ID
  • x,y:左上角起始位置
  • w,h:控件的宽度、高度
--设置画面0控件ID10显示在(476,70)位置,大小为120,36
wgt_set_pos(0,10,476,70,120,36)

10.5 wgt_set_fcolor(screen,control, color)

设置控件的前景色:如文本控件、进度条控件

  • screen:画面ID
  • control:控件ID
  • color:颜色RGB565
--设置画面0控件ID10的前景色
wgt_set_fcolor(0,10,0xF800) --红色
wgt_set_fcolor(0,10,0x07E0) --绿色
wgt_set_fcolor(0,10,0xFFE0) --黄色

10.6 wgt_set_bcolor(screen,control, color)

设置控件的背景色:如文本控件、进度条控件

  • screen:画面ID
  • control:控件ID
  • color:颜色RGB565
--设置画面0控件ID10的背景色
wgt_set_bcolor(0,10,0xF800) --红色
wgt_set_bcolor(0,10,0x07E0) --绿色
wgt_set_bcolor(0,10,0xFFE0) --黄色

10.7 wgt_set_param(screen,control, param,value)

设置控件的属性接口,保留扩展接口

  • screen:画面ID
  • control:控件ID
  • param:设置标识码
    • 0x30:表示数据记录控件的通道翻页
    • 0x31:表示曲线控件的Y轴最小值
    • 0x32:表示曲线控件的Y轴最大值
  • value:数据内容
--设置画面0,控件ID10的曲线控件最大值、最小值
wgt_set_param(0,10, 0x32,100) --最大值100
wgt_set_param(0,10, 0x31,0)   --最小值10

10.8 on_wgt_event(screen_id,widget_id,event,value)

窗口设置触发回调,控件id不为0,触碰控件,自动触发该函数

设置控件的属性接口,保留扩展接口

  • screen:画面ID
  • control: 控件ID
  • event:触发的事件

  • value:单位控件绑定寄存器的值

10.9 refresh_screen()

立即刷新画面

11 简易数据库

ViusualHMI 的数据库是以字符串写入flash,一般屏幕默认为16M。

用户计算需要存储的条数、一条数据的大小。推算出数据库的起始地址。如需要记录1000条记录,每条1000个字节,占用大小为976.5625 k(不满1M)

其中工程4.36M;引导程序(BOOT)+ 固件,一共 1M;至少在6M开始存储。

同时需要考虑资料采集、告警、操作记录等存储控件是否两两交叉。

image-20231107164331489

定义如下:从第10M开始存储,若数据库不存在,新建打开。

db = {}

db.param = {
    flashaddr        = 10*1024*1024, --从falsh 10M开始存储
    createIfNotExist = 1,            --数据库不存在,新建
    dataRowSize      = 1000,         --一条记录1000字节
    maxCount         = 1000,         --记录1000条
}

11.1 easydb_open(flashaddr,createIfNotExist,dataRowSize,maxCount)

打开数据库

  • flashaddr:Flash 地址
  • createIfNotExist: 0-打开,1-文件不存在创建打开
  • dataRowSize:一条数据的大小
  • maxCount:最大数据数
--返回句柄
local dbhandle =  easydb_open(flashaddr,createIfNotExist,dataRowSize,maxCount)

11.2 easydb_close(db)

关闭数据库

  • db:数据库句柄
easydb_close(dbhandle)

11.3 easydb_get_count(db)

获取数据库当前条数

  • db:数据库句柄
--获取数据库的总条数
function db.getCnt()

    local dbhandle = easydb_open(db.param.flashaddr, db.param.createIfNotExist, db.param.dataRowSize, db.param.maxCount)
    local ret = easydb_get_count(dbhandle)
    easydb_close(dbhandle)

    return ret
end

11.4 easydb_get(db,idx)

读取指定行的数据库数据

  • db:数据库句柄
  • idx:指定行
--读取:数据库某一条内容
function db.get(idx)

    local ret
    local dbhandle = easydb_open(db.param.flashaddr, db.param.createIfNotExist, db.param.dataRowSize, db.param.maxCount)
    local count = easydb_get_count(dbhandle)

    if idx <= count
    then
        ret = easydb_get(dbhandle, idx-1)
    end

    return ret
end

11.5 easydb_add(db,dataset)

  • db:数据库句柄
  • dataset:添加的内容
--写入:一条数据内容
function db.add(msg)
    local ret
    local dbhandle = easydb_open(db.param.flashaddr, db.param.createIfNotExist, db.param.dataRowSize, db.param.maxCount)
    local count = easydb_get_count(dbhandle)

    if count < db.param.maxCount
    then
        ret = easydb_add(dbhandle, msg)
    end

    return ret
end

11.6 easydb_update(db,idx,dataset)

修改数据库指定行内容

  • db:数据库句柄
  • idx:第几行
  • dataset:添加的内容
--修改:数据库某一条内容
function db.modify(idx, msg)

    local ret
    local dbhandle = easydb_open(db.param.flashaddr, db.param.createIfNotExist, db.param.dataRowSize, db.param.maxCount)
    local count = easydb_get_count(dbhandle)

    if idx <= count
    then
        ret = easydb_update(dbhandle, (idx - 1), msg)
    else
        ret = -1
    end

    return ret
end

11.7 easydb_del(db,idx)

删除数据库指定行内容

  • db:数据库句柄
  • idx:第几行
--删除:数据库某一条内容
function db.del(idx)

    local ret
    local dbhandle = easydb_open(db.param.flashaddr, db.param.createIfNotExist, db.param.dataRowSize, db.param.maxCount)
    local count = easydb_get_count(dbhandle)

    if idx <= count
    then
        ret = easydb_delete(dbhandle, idx-1)
    else
        ret = -1
    end

    return ret
end

11.8 easydb_clear(db)

清除数据库

  • db:数据库句柄
--清除:清除数据库
function db.clear(idx)
    local dbhandle = easydb_open(db.param.flashaddr, db.param.createIfNotExist, db.param.dataRowSize, db.param.maxCount)
    easydb_clear(dbhandle)
end

12 GPIO控制

GPIO控制,需要看硬件是否引出IO引脚,以HMI48272KM043 硬件为例,PD20、PD21,IO定义如下:

16进制的高八位表示IO组,低八位表示引脚

LED1 = 0x0314
LED2 = 0x0315

12.1 gpio_set_in (pin)

PIN引脚设置为输入模式

gpio_set_in(LED1)
gpio_set_in(LED2)

12.2 gpio_set_out (pin)

PIN引脚设置为输出模式

12.3 gpio_set_value (pin,value)

设置输出PIN引脚为(高电平1/低电平0)

gpio_set_value(LED1,0) --IO输出0
gpio_set_value(LED2,1) --IO输出1

12.4 gpio_get_value (pin)

获取输入PIN引脚电平(高电平1/低电平0)

local val = gpio_get_value (LED1)

> val = 1 --逻辑1
> val = 0 --逻辑0

13 其他

13.1 get_platform()

获取屏幕芯片信息,返回字符串类型,设备型号

local device = get_platform()

13.2 get_version()

获取固件版本号,返回数值

local ver= get_version()

13.3 get_device_uuid()

获取设备唯一表示符号,返回长度为20的数字字符串

13.4 reboot()

屏幕复位

13.5 feed_dog()

在某个操作执行耗时超过5秒,需要执行喂狗

for i = 0, 10000 --某循环体大
do
    feed_dog()
    --do user code
end

13.6 delay_ms(ms)

延时函数,单位ms,延时不宜过长,超过5秒回复位

13.7 set_run_cycle(cycle)

设置on_run的执行周期,毫秒单位。

[!note|tip:注意] 不要在on_run 里面调用set_run_cycle(cycle)

function on_init()
    set_run_cycle(1000) --on_run(screen)  1s回调一次
end

13.8 update_system()

立刻加载、写入系统参数。如声音、多语言、音频音量大小、背光设置、用户密码、分期使用参数、配方等

例如:加载系统语言:

function on_init()
    set_uint16(VT_LW, 0x011B, (1<<1)) -- 选择需要加载的掩码,bit1,多语言
    set_uint16(VT_LW, 0x011A, 0x5502) -- 加载选中的系统参数
    update_system()
end

function on_update(slave,vtype,addr)
    if vtype == VT_LW
    then
        if addr == 0x119
        then
            set_uint16(VT_LW, 0x011B, (1<<1)) -- 选择需要加载的掩码,bit1,多语言
            set_uint16(VT_LW, 0x011A, 0x5501) -- 保存选中的系统参数
            update_system()
        end
    end
end

例如:配方清0

for i = 0, 41
do
    feed_dog()
    set_uint16(VT_LW, 0x1000, i)
    update_system()--立刻加载

    local recoveryTb = {}
    for j = 1, 32
    do
        recoveryTb[j] = 0
    end

    set_array(VT_LW, 0x1001, recoveryTb)
    set_uint16(VT_LW, 0x1100, 2)
    update_system()--立刻写入
end

13.9 get_date_time ()

获取当前日期时间

local year,mon,day,hour,min,sec,week = get_date_time()

13.10 set_date_time (year,mon,day,hour,min,sec)

设置当前日期时间

set_date_time(2023,8,8,8,8,8)

13.11 make_datetime(timestamp)

时间戳转年月日时分秒

local year,mon,day,hour,min,sec = make_datetime(timestamp)

13.12 make_timestamp(year,mon,day,hour,min,sec)

年月日时分秒转时间戳

local timestamp = make_timestamp(year,mon,day,hour,min,sec)

13.13 set_pwd(level,pwd,len)

设置对应等级用户的密码

  • level: 用户等级0~7
  • pwd: 用户数字密码
  • len:选填,前导0,如设置4,密码为123,正确需要输入0123

无前导零,设置修改1级密码并存储,如下所示:

set_pwd(0,123)
set_uint16(VT_LW, 0x011B, (1<<4))-- 选择用户密码系统参数
set_uint16(VT_LW, 0x011A, 0x5501)-- 保存密码

前导零,设置修改1级密码并存储,如下所示:

set_pwd(0,123,4)
set_uint16(VT_LW, 0x011B, (1<<4)) --选择用户密码系统参数
set_uint16(VT_LW, 0x011A, 0x5501) --保存密码

上电加载安全等级密码

function on_init()
    set_uint16(VT_LW, 0x011B, (1<<4)) --选择用户密码系统参数
    set_uint16(VT_LW, 0x011A, 0x5502) --加载密码
    update_system()
end

13.14 set_stage_pwd(level,pwd)

设置对应的分期密码

  • level: 用户等级0~9
  • pwd: 用户数字密码

无前导零,设置修改1级密码并存储,如下所示:

set_stage_pwd(0,1234)
set_uint16(VT_LW, 0x011B, (1<<5))-- 选择分期密码系统参数
set_uint16(VT_LW, 0x011A, 0x5501)-- 保存密码

上电加载分期密码

function on_init()
    set_uint16(VT_LW, 0x011B, (1<<5)) --选择分期密码系统参数
    set_uint16(VT_LW, 0x011A, 0x5502) --加载密码
    update_system()
end

13.15 flash_sync()

立刻写入flash

function writeMsgToRw()
    rwMsgAddr = 0x4000
    for i = 1, 300
    do
        set_string(VT_RW, rwMsgAddr, fileMsgTb[i])
        rwMsgAddr = rwMsgAddr + 16
        feed_dog()
    end
    flash_sync()
end

13.16 md5(text, key)

基于Hash函数和密钥进行消息认证的方法,通过这个算法可以保证通信双方之前交互的消息来自对方并且没有被篡改,返回一个长度为32的16进制字符

  • text:目标字符串
  • key:双方规约的密钥
Copyright ©Dacai all right reserved,powered by Gitbook该文件修订时间: 2024-03-14 15:24:23

results matching ""

    No results matching ""